<?php

namespace BreakCode\Connector;

use BreakCode\BaseInterface\Connector;
use BreakCode\BaseInterface\Launch;
use BreakCode\BaseInterface\Response;
use GuzzleHttp\Exception\GuzzleException;

class SuAn extends Connector implements Launch
{

    protected $passStr;

    protected $type = '1001';

    protected $reBate;

    protected $host;

    protected $error;

    /**
     * @throws GuzzleException
     */
    public function __construct()
    {
        $this->host = $this->getHost();
    }

    /**
     * @throws GuzzleException
     */
    public function identify(string $file, bool $base64 = false): Response
    {
        $flag = 0;//当上传图片功能返回值“连续2次”带有“<”或者“”时更换HOST（第2步），再执行本操作 记录出现次数

        $answer = new Response('200', '', '');

        while (true) {
            if ($flag >= 2) {
                $this->host = $this->getHost();
                $flag = 0;
            }
            if (!$base64) {
                $img = file_get_contents($file);
                $img = base64_encode($img);//转换为base64
            } else {
                if (strpos($file, 'base64,')) {
                    $file = substr($file, strpos($file, 'base64,')+7);
                }
                $img = $file;
            }

            $url = $this->host . "/UploadBase64.aspx";//获取URL
            $post = array(
                'UserStr' => $this->passStr,//UserStr：用户密码串
                'GameID' => $this->type,    //GameID：题目类型
                'TimeOut' => '30',          //TimeOut：超时时间
                'Rebate' => $this->reBate,  //Rebate	：软件key
                'DaiLi' => 'haoi',          //DaiLi：固定"haoi"
                'Kou' => '0',               //Kou：自定义扣分
//                'BeiZhu' => '',           //BeiZhu：备注信息
                'Ver' => 'web2',            //x Ver：版本号
                'Key' => $this->getRandom(),//Key	：随机数（10位）
                'Img' => $img,              //Img：图片字节流Base64编码后的字符串
                'r' => $this->getRandom(),
            );

            $response = $this->request($url, "POST", $post);
            $point = $response->getBody();//获取题目编号

            if (!strstr($point, "#") and $point)//判断是否包含"#" 且不为空
            {
                //                echo '题目编号：'.$point;
                $response = $this->getAnswer($point, $answer);//获取答案
                $s = $response->getBody();
                if (strstr($s, "#") or $s == "") {
                    if (strstr($s, "<") || $s == "") {
                        $flag = $flag + 1;
                        continue;
                    }
                    $response->setError("提交失败，错误原因为：{$s}");
                }
            } else {
                $response->setError("提交失败，错误原因为：{$point}");
            }
            return $response;
        }
    }

    /**
     * @throws GuzzleException
     */
    private function getHost()
    {
        $s2 = true;
        while (true) {
            if ($s2) {
                //返回数据示例：===sv11.haoi23.net:8009--sv12.haoi23.net:8009+++
                $s = $this->request("http://2.haoi23.net/svlist.html")->getBody();
                if ($s == "") {
                    $s2 = false;
                    continue;
                }
            } else {
                $s = $this->request("http://0.haoi23.net/svlist.html")->getBody();
                if ($s2 == "") {
                    $s2 = true;
                    continue;
                }
            }
            if (strstr($s, "+++") and strstr($s, "===")) {
                return $this->getHostData($s);
            }
        }
    }

    //提取获得的主机号
    private function getHostData($s)
    {
        $s = trim($s, "===");
        $s = trim($s, "+++");
        $s = explode("--", $s);
        $index = count($s) - 1;
        $index = rand(0, $index);
        return $s[$index];//返回host
    }

    //生成随机数
    private function getRandom(): string
    {
        $i = 10;
        $str = "0123456789abcdefghijklmnopqrstuvwxyz";
        $finalStr = "";
        for ($j = 0; $j < $i; $j++) {
            $finalStr .= substr($str, rand(0, 35), 1);
        }
        return $finalStr;
    }

    //获取答案（发送题目后循环每秒调用一次获取答案，直至返回值不为空字符串""，结束整个发题函数）

    /**
     * @throws GuzzleException
     */
    private function getAnswer($tid, Response $answer): Response
    {
        while (true) {
            $url = $this->host . "/GetAnswer.aspx";
            $post = [
                'ID' => $tid, //ID：题目编号
                'r' => $this->getRandom() //r:随机数
            ];

            $response = $this->requestOne($answer, $url, 'POST', $post);

            $point = $response->getBody();//获取答案
            if ($point)//直到获取到答案 返回答案
            {
                return $answer;
            }
        }
    }
}
